package com.freejava.myblog.interceptor;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;

import com.freejava.myblog.annotation.PassToken;
import com.freejava.myblog.annotation.UserLoginToken;
import com.freejava.myblog.common.BusinessException;
import com.freejava.myblog.config.UserContext;
import com.freejava.myblog.pojo.MyUser;
import com.freejava.myblog.services.UserService;
import com.freejava.myblog.tools.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws BusinessException {
        // 从请求头中获取token数据
        String token = request.getHeader("token");
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.requried()) {
                return true;
            }
        }

        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                if (token == null) {
                    throw new BusinessException("4001", "no token");
                }

                // todo Continue to check the user valid.
                String userId;
                try {
                    userId = JWT.decode(token).getAudience().get(0);

                } catch (Exception e) {
                    throw new BusinessException("4003", "decode token fails");
                }
                // Check the expire of token.
//                String tokenKey = userId + ":" + token;
//                boolean hasExisted = redisUtil.hasKey(tokenKey);
//                System.out.println("exist or not:" + hasExisted);
//                if (hasExisted == false) {
//                    throw new BusinessException("4005", "token expired!");
//                }
                int userID = Integer.parseInt(userId);
                System.out.println("usrId is:" + userID);
                MyUser user = userService.findUserById(userID);
                if (user == null) {
                    throw new RuntimeException("user not exists");
                }
                try {
                    JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword() + "MText!76&sQ^")).build();
                    jwtVerifier.verify(token);
                    // 设置当前登录用户
                    LoginUser loginUser = new LoginUser();
                    loginUser.setId(userID);
                    loginUser.setName(user.getName());
                    UserContext.setUser(loginUser);
                    return true;
                } catch (JWTVerificationException e) {
                    throw new BusinessException("4002", "invalid token!");
                }
            }
        }
        // 如果一个接口没有添加UserLoginToken注册，那么也会直接放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

